﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

namespace Nirvana
{
    /// <summary>
    /// 多边形雷达网格线
    /// </summary>
    [AddComponentMenu("Nirvana/UI/Effects/Radar Chart Line")]
    public class RadarChartLine : Graphic
    {
        [Range(3f, 30f)]
        [SerializeField]
        private int verticesCount = 5;

        [SerializeField]
        [Range(0f, 1f)]
        private float maxVolume = 1f;

        [SerializeField]
        [Range(0.001f, 0.03f)]
        private float lineWidth = 0.02f;

        [SerializeField]
        private bool drawMajorGrid = true;

        [SerializeField]
        [Range(0.01f, 1f)]
        private float majorGridInterval = 0.2f;


        protected override void OnPopulateMesh(VertexHelper vh)
        {
            vh.Clear();
            if (this.maxVolume == 0) return;
            UIVertex simpleVert = UIVertex.simpleVert;
            simpleVert.color = this.color;
            this.UpdateVertex(vh, this.maxVolume);
            this.UpdateVertex2(vh, this.maxVolume);
            if(this.drawMajorGrid && this.majorGridInterval < this.maxVolume)
            {
                int num = (int)(this.maxVolume / this.majorGridInterval);
                for (int i = 1; i <= num; i++)
                {
                    this.UpdateVertex(vh, (float)i * this.majorGridInterval);
                }
            }


        }

        private void UpdateVertex(VertexHelper vh,float volume)
        {
            int currentVertCount = vh.currentVertCount;
            UIVertex simpleVert = UIVertex.simpleVert;
            simpleVert.color = this.color;
            float avgHalfAngle = 360f / this.verticesCount * 0.5f;
            float lineAngle = this.lineWidth / Mathf.Cos(avgHalfAngle * Mathf.Deg2Rad) / 2f;
            float avgAngle = 360f / this.verticesCount;
            for(int i = 0; i < this.verticesCount; i++)
            {
                float angle = (90 - avgAngle * i) * Mathf.Deg2Rad;
                float x = Mathf.Cos(angle);
                float y = Mathf.Sin(angle);
                float px0 = 0.5f + x * (0.5f*volume -lineAngle);
                float py0 = 0.5f + y * (0.5f * volume - lineAngle);

                float px1 = 0.5f + x * (0.5f * volume + lineAngle);
                float py1 = 0.5f + y * (0.5f * volume + lineAngle);

                Vector2 pos0 = this.ModifyVertex(px0, py0);
                Vector2 pos1  = this.ModifyVertex(px1, py1);
                simpleVert.position = pos0;
                vh.AddVert(simpleVert);
                simpleVert.position = pos1;
                vh.AddVert(simpleVert);

                int trianleCount = this.verticesCount * 2;
                int curTrianle = i * 2;
                int nextTrianle = (i + 1) * 2;
                int idx0 = curTrianle % trianleCount + currentVertCount;
                int idx1 = (curTrianle + 1) % trianleCount + currentVertCount;

                int idx2 = nextTrianle % trianleCount + currentVertCount;
                int idx3 = (nextTrianle + 1) % trianleCount + currentVertCount;
                vh.AddTriangle(idx0, idx1, idx2);
                vh.AddTriangle(idx2, idx1, idx3);

            }
        }

        private void UpdateVertex2(VertexHelper vh, float volume)
        {
            int currentVertCount = vh.currentVertCount;
            UIVertex simpleVert = UIVertex.simpleVert;
            simpleVert.color = this.color;
            float lineAngle = 90* this.lineWidth / (volume * 1.5707964f);//Mathf.PI/2=1.5707964f
            float avgAngle = 360f / this.verticesCount;
            for (int i = 0; i < this.verticesCount; i++)
            {
                float angleMin = (90 - lineAngle - avgAngle * i) * Mathf.Deg2Rad;
                float angleMax = (90 + lineAngle - avgAngle * i) * Mathf.Deg2Rad;

                float MinX = 0.5f + Mathf.Cos(angleMin) * 0.5f * volume;
                float MinY = 0.5f + Mathf.Sin(angleMin) * 0.5f * volume;
                float MaxX = 0.5f + Mathf.Cos(angleMax) * 0.5f * volume;
                float MaxY = 0.5f + Mathf.Sin(angleMax) * 0.5f * volume;

                float x0 = 0.5f + (MinX - MaxX) / 2f;
                float y0 = 0.5f + (MinY - MaxY) / 2f;
                float x1 = 0.5f + (MaxX - MinX) / 2f;
                float y1 = 0.5f + (MaxY - MinY) / 2f;

                Vector2 v0 = this.ModifyVertex(x0, y0);
                Vector2 v1 = this.ModifyVertex(x1, y1);
                Vector2 v2 = this.ModifyVertex(MinX, MinY);
                Vector2 v3 = this.ModifyVertex(MaxX, MaxY);
                simpleVert.position = v0;
                vh.AddVert(simpleVert);
                simpleVert.position = v1;
                vh.AddVert(simpleVert);
                simpleVert.position = v2;
                vh.AddVert(simpleVert);
                simpleVert.position = v3;
                vh.AddVert(simpleVert);

                int t0 = i * 4 + currentVertCount;
                int t1 = i * 4 + 3 + currentVertCount;
                int t2 = i * 4 + 2 + currentVertCount;
                int t3 = i * 4 + 1 + currentVertCount;
                vh.AddTriangle(t0, t1, t2);
                vh.AddTriangle(t0, t3, t1);
            }
        }
        private Vector2 ModifyVertex(float x, float y)
        {
            Vector2 pivot = this.rectTransform.pivot;
            Rect rect = this.rectTransform.rect;
            Vector2 vertex = Vector2.zero;
            vertex.x -= pivot.x;
            vertex.y -= pivot.y;
            vertex.x += x;
            vertex.y += y;
            vertex.x *= rect.width;
            vertex.y *= rect.height;
            return vertex;
        }

    }
}


